from sys import argv
from math import sin, cos, radians
from numpy import identity, array
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

class MyPyOpenGLTest:
    def __init__(self, width=640, height=480,
                 title='PyOpenGL二维变换'.encode('gbk')):
        '''初始化OpenGL环境，指定显示模式以及用于绘图的函数'''
        glutInit(argv)
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
        # 设置图形窗口初始大小和位置，然后创建图形窗口，顺序不能变
        glutInitWindowSize(width, height)
        glutInitWindowPosition(400, 200)
        glutCreateWindow(title)
        glutDisplayFunc(self.draw)
        # glutReshapeFunc(self.reshape)
        self.initGL(width,height);
        glutIdleFunc(self.draw)
        glClearColor(1.0, 1.0, 1.0, 1.0)
        self.objects = ("", "球", "立方体", "茶壶");

    # 根据特定的需要，进一步完成OpenGL的初始化
    def InitGL(self, width, height):
        # 初始化窗口背景为白色
        glClearColor(1.0, 1.0, 1.0, 1.0)
        # 切换到透视投影矩阵
        glMatrixMode(GL_PROJECTION)
        # 加载单位矩阵，重置
        glLoadIdentity()
        gluOrtho2D(0, width, 0, height)

        # 设置光滑渲染
        glEnable(GL_BLEND)
        glShadeModel(GL_SMOOTH)
        glEnable(GL_POINT_SMOOTH)
        glEnable(GL_LINE_SMOOTH)
        glEnable(GL_POLYGON_SMOOTH)

        # 设置反走样/抗锯齿算法
        glHint(GL_POINT_SMOOTH_HINT, GL_NICEST)
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
        glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST)

        # 设置光照效果
        glLightfv(GL_LIGHT0, GL_POSITION, (0, 3, 3, 0))
        glLightfv(GL_LIGHT0, GL_AMBIENT, (0.1, 0.1, 0.1, 1))
        glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.6, 0.6, 0.6, 1))
        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)

        # 是的材质对当前光照进行跟踪

        # 切换到透视投影矩阵
        glMatrixMode(GL_PROJECTION)
        # 加载单位矩阵，重置
        glLoadIdentity()
        # 参数分别表示角度、宽/高比、视景体近处zNear、视景体远处zFar
        gluPerspective(45, width / height, 1, 10)

        # 切换到模型观察矩阵，参数可能的取值还有GL_TEXTURE
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        # 切换到模型观察矩阵
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

    def mouse_downup(self, button, state, x, y):
        pass

    def do_selection(self, x, y ):
        pass
        selection_buffer = glSelectBuffer(16)
        viewport =glGetIntegerv(GL_VIEWPORT)
        glMatrixMode(GL_PROJECTION)
        glPushMatrix()
        glRenderMode(GL_SELECT)
        glLoadIdentity()
        gluPickMatrix(x, viewport[3]-y, 2, 2, viewport)
        aspect = viewport[2] / viewport[3]
        gluPerspective(45, aspect, 1, 100)
        self.draw()
        hits = glRenderMode(GL_RENDER)
        if hits:
            label = self.objects[selection_buffer[3]]
            glutSetWindowTitle(f'选择物体-选中了{label}'.encode('gbk'))
        else:
            glutSetWindowTitle("选择物体-没选择任何物体".encode('gbk'))






    def draw(self):
        '''自己的绘图方法，本程序的关键'''
        # 每次绘制图形之前清除颜色缓冲区和深度缓冲区中的信息
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        # 切换到模型观察矩阵，才能正确绘制图形
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glInitNames()
        glPushName(0)

        glColor3f(1, 0.5, 0.5)
        glPushMatrix()
        glTranslatef(-10, 0, -35)
        glLoadName(self.objects.index('球'))
        glutSolidSphere(4, 30, 30)
        glPopMatrix()

        glColor3f(1, 0.5, 0.5)
        glPushMatrix()
        glTranslatef(0, 0, -35)
        glRotatef(30, 1, 0, 0)
        glLoadName(self.objects.index('立方体'))
        glutSolidCube(5)
        glPopMatrix()

        glColor3f(0, 1, 1)
        glPushMatrix()
        glTranslatef(10, 0, -35)
        glRotatef(30, 1, 0, 0)
        glLoadName(self.objects.index('茶壶'))
        glutSolidTeapot(4)
        glPopMatrix()


        # 交换缓冲区，更新图形
        glutSwapBuffers()

    # 消息主循环
    def mainloop(self):
        glutMainLoop()

if __name__ == '__main__':
    # 创建窗口对象，启动消息主循环
    MyPyOpenGLTest().mainloop()
